package vip.liux.backend.adapter.web;

import com.google.common.collect.Maps;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.*;
import vip.liux.application.dots.ListResultDto;
import vip.liux.application.dots.PagedResultDto;
import vip.liux.backend.application.service.pay.PayOrderService;
import vip.liux.backend.application.service.pay.PayWalletService;
import vip.liux.backend.application.service.pay.dto.order.*;
import vip.liux.backend.application.service.pay.dto.wallet.PayWalletDto;
import vip.liux.backend.application.serviceImpl.pay.client.WalletPayClient;
import vip.liux.contracts.shared.enums.pay.PayChannelCode;
import vip.liux.contracts.shared.enums.pay.PayOrderStatus;
import vip.liux.core.current.ICurrentUser;

import java.math.BigDecimal;
import java.util.Collection;
import java.util.Objects;
import java.util.Optional;

import static vip.liux.backend.infrastructure.utils.ServletUtil.getClientIP;

/**
 * 支付订单管理 API
 */
@RestController
@RequestMapping("/api/pay/order")
public class PayOrderController {

    @Resource
    private PayOrderService payOrderService;
    @Resource
    private PayWalletService walletService;
    @Resource
    private ICurrentUser<Long> currentUser;

    /**
     * 获取单个支付订单
     */
    @GetMapping("/{id}")
    public PayOrderDto getOrder(
            @PathVariable Long id,
            @RequestParam(value = "sync", required = false) Boolean sync) {
        PayOrderDto order = payOrderService.getOrder(id);
        // sync 仅在等待支付
        if (Boolean.TRUE.equals(sync) && PayOrderStatus.isWaiting(order.getStatus())) {
            payOrderService.syncOrderQuietly(order.getId());
            // 重新查询，因为同步后，可能会有变化
            order = payOrderService.getOrder(id);
        }
        return order;
    }

    /**
     * 获取单个支付订单
     */
    @GetMapping("/orderNo/{orderNo}")
    public PayOrderDto getByOrderNo(
            @PathVariable String orderNo,
            @RequestParam(value = "sync", required = false) Boolean sync) {
        PayOrderDto order = payOrderService.getByOrderNo(orderNo);
        // sync 仅在等待支付
        if (Boolean.TRUE.equals(sync) && PayOrderStatus.isWaiting(order.getStatus())) {
            payOrderService.syncOrderQuietly(order.getId());
            // 重新查询，因为同步后，可能会有变化
            order = payOrderService.getByOrderNo(orderNo);
        }
        return order;
    }
    /**
     * 获取单个支付订单
     */
    @GetMapping("/detail/{id}")
    public PayOrderDetailsDto getOrderDetail(@PathVariable Long id) {
        return payOrderService.getOrderDetail(id);
    }

    @PostMapping("/submit")
    public PayOrderSubmitDto submitOrder(@RequestBody PayOrderSubmitInputDto inputDto) {
        // 1. 钱包支付事，需要额外传 user_id 和 user_type
        if (Objects.equals(inputDto.getChannelCode(), PayChannelCode.WALLET.getCode())) {
            if (inputDto.getChannelExtras() == null) {
                inputDto.setChannelExtras(Maps.newHashMapWithExpectedSize(1));
            }
            PayWalletDto wallet = walletService.getOrCreateWallet(Optional.ofNullable(currentUser.getId()).map(Object::toString).orElseThrow());
            inputDto.getChannelExtras().put(WalletPayClient.WALLET_ID_KEY, String.valueOf(wallet.getId()));
        }
        return payOrderService.submitOrder(inputDto, getClientIP());
    }

    /**
     * 根据应用ID和商户订单号获取支付订单
     */
    @GetMapping("/byMerchantOrderId")
    public PayOrderDto getOrderByMerchantOrderId(
            @RequestParam Long appId,
            @RequestParam String merchantOrderId) {
        return payOrderService.getOrder(appId, merchantOrderId);
    }

    /**
     * 获取多个支付订单列表
     */
    @GetMapping("/list")
    public ListResultDto<PayOrderDto> getOrderList(@RequestParam Collection<Long> ids) {
        return payOrderService.getOrderList(ids);
    }

    /**
     * 获取指定应用的订单数量
     */
    @GetMapping("/count/{appId}")
    public Long getOrderCountByAppId(@PathVariable Long appId) {
        return payOrderService.getOrderCountByAppId(appId);
    }

    /**
     * 分页获取支付订单
     */
    @GetMapping("/page")
    public PagedResultDto<PayOrderDto> getOrderPage(PayOrderQueryDto pageDto) {
        return payOrderService.getOrderPage(pageDto);
    }

    /**
     * 获取用于Excel导出的支付订单列表
     */
    @GetMapping("/export")
    public ListResultDto<PayOrderDto> getOrderListForExport(PayOrderExportDto exportDto) {
        return payOrderService.getOrderList(exportDto);
    }

    /**
     * 更新支付订单的退款金额
     */
    @PutMapping("/{orderNo}/refundPrice")
    public void updateOrderRefundPrice(
            @PathVariable String orderNo,
            @RequestParam BigDecimal incrRefundPrice) {
        payOrderService.updateOrderRefundPrice(orderNo, incrRefundPrice);
    }

    /**
     * 更新支付订单价格
     */
    @PutMapping("/{orderNo}/payPrice")
    public void updatePayOrderPrice(
            @PathVariable String orderNo,
            @RequestParam BigDecimal payPrice) {
        payOrderService.updatePayOrderPrice(orderNo, payPrice);
    }

    /**
     * 过期订单处理（将已过期订单状态修改为已关闭）
     */
    @PostMapping("/expire")
    public int expireOrder() {
        return payOrderService.expireOrder();
    }
}